from event_handler import Event
from abc import ABC, abstractmethod
import time

class State(ABC):
    """状态基类"""
    @abstractmethod
    def handle(self, tank, event):
        pass

class Idle(State):
    """空闲状态"""
    def handle(self, tank, event):
        if event == Event.START:
            print("水箱启动，进入 Idle 状态")
        elif event == Event.WATER_DETECTED and tank.temperature < 20:
            print("检测到水且温度 < 20°, 进入 Heating 状态")
            tank.set_state(Heating())
        elif event == Event.NO_WATER:
            print("无水，进入 NoWater 状态")
            tank.set_state(NoWater())
        elif event == Event.TIME_23:
            print("晚上23:00, 进入 SleepMode")
            tank.set_state(SleepMode())

class Heating(State):
    """加热状态"""
    def handle(self, tank, event):
        if event == Event.TEMP_ABOVE_100:
            print("温度 >= 100°, 进入 PowerOff 状态")
            tank.set_state(PowerOff())
        elif event == Event.BURNED_OUT:
            print("水箱烧坏，进入 BurnedOut 状态")
            tank.set_state(BurnedOut())

class NoWater(State):
    """无水状态"""
    def handle(self, tank, event):
        if event == Event.WATER_DETECTED and tank.temperature < 20:
            print("检测到水且温度 < 20°, 返回 Idle 状态")
            tank.set_state(Idle())

class PowerOff(State):
    """电源关闭状态"""
    def handle(self, tank, event):
        if tank.temperature < 20 and 7 <= time.localtime().tm_hour < 23:
            print("温度 < 20° 且时间在 7:00 - 23:00 之间，返回 Idle 状态")
            tank.set_state(Idle())

class BurnedOut(State):
    """烧坏状态"""
    def handle(self, tank, event):
        if event == Event.MAINTENANCE:
            print("进入维修状态")
            tank.set_state(Maintenance())

class SleepMode(State):
    """休眠模式"""
    def handle(self, tank, event):
        if event == Event.TIME_7:
            print("早上7:00，退出休眠模式")
            tank.set_state(Idle())

class Maintenance(State):
    """维修状态"""
    def handle(self, tank, event):
        if event == Event.REPAIRED:
            print("维修完成，返回 Idle 状态")
            tank.set_state(Idle())

